﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using AiFrame.Interface.WinUI.Windows.Controls;
using AiFrame.InterfaceLib.Data.Patterns;
using AiFrame.InterfaceLib.MVP;
using AiFrame.InterfaceLib.Plugins;
using AiFrame.InterfaceLib.Windows.Controls;
using AiFrame.Windows.Controls.DataNavigationBar;

namespace AiFrame.Interface.WinUI.Windows.UI
{
    /// <summary>
    /// Implementiert ein Container-Fenster für Data-Views.
    /// </summary>
    public partial class AbstractContainerWindow<T> : Form, IDataContainerViewEx<T>
    {
        private PictureBox _headerPictureBox;
        
        private Image _headerLogo;
        private ToolStripContainer _toolStripContainer;
        private ToolStrip _toolStrip;
        private IStyleGuideUI _styleGuide;
        private ICoreInterface _ci;
        protected IDataNavigationBar _navigationBar;
        protected Splitter _splitter;
        protected IControllableDataWindowManager<IControllableDataWindowEx<T>> _wndManager;
        protected IDataSourceProvider<T> _dataSourceProvider;
        private Image _backgroundImage;
        private Panel headerPanel;

        public AbstractContainerWindow()
        {
            InitializeComponent();
            
        }

        protected virtual string GetHeaderText()
        {
            return "Data Window";
        }

        protected virtual string GetTitleText()
        {
            return "Daten bearbeiten";
        }

        protected void Initialize(IStyleGuideUI styleGuideUI, ICoreInterface ci, T businessObject,
                IDataSourceProvider<T> dataSourceProvider, Image headerImage)
        {
            _styleGuide = styleGuideUI;
            _ci = ci;
            _dataSourceProvider = dataSourceProvider;
            DataChanged = false;
            Text = GetTitleText();

            /* Header-Logo laden */
            _headerLogo = headerImage;
            if (_headerLogo == null)
            {
                _headerLogo = _ci.Theme.GetDataWindowHeaderIcon();
            }
            

            /* Header-Box erstellen */
            headerPanel = new Panel()
                              {
                                  Parent = this,
                                  Dock = DockStyle.Top,
                                  Height = _ci.StyleGuideUI.GetDataWindowHeaderHeight(),
                                  BackColor = Color.White
                              };
            
            BevelControl topBevel = new BevelControl()
                                        {
                                            Parent = headerPanel,
                                            Dock = DockStyle.Fill,
                                            BevelType = BevelType.BottomLine,
                                        };
            _backgroundImage = _ci.Theme.GetDataWindowBgLogo();
            topBevel.Paint +=new PaintEventHandler(_headerPictureBox_Paint);

            /* Tool-Strip hinzufügen */
            _toolStripContainer = new ToolStripContainer
            {
                Parent = backPanel,
                Dock = DockStyle.Fill
            };
            _toolStrip = new ToolStrip { Parent = _toolStripContainer.TopToolStripPanel };

            _splitter = new Splitter { Parent = contentPanel, Dock = DockStyle.Left,
            BorderStyle = BorderStyle.FixedSingle};

            /* DataNavigationBar erzeugen */
            _navigationBar = new DataNavigationBar(_ci.Theme);
            _navigationBar.SetParent(contentPanel);
            _navigationBar.SetDockingStyle(DockStyle.Left);

//            gradientPanel1.GradientStartColor = _ci.Theme().GetPanelBeginColor();
//            gradientPanel1.GradientEndColor = _ci.Theme().GetPanelEndColor();
            
            /* Den Window-Manager initialisieren */
            _dataSourceProvider.SetDataSource(businessObject);


            var wm = new ControllableDataWindowManager<T>();
            wm.Initialize(pluginPanel, _navigationBar, _dataSourceProvider);
            _wndManager = wm;
            _wndManager.WindowRegistered += new EventHandler<WindowRegisteredEventArgs<IControllableDataWindowEx<T>>>(_wndManager_WindowRegistered);
            
        }

        void _wndManager_WindowRegistered(object sender, WindowRegisteredEventArgs<IControllableDataWindowEx<T>> e)
        {
            e.Window.SetContainerView(this);
        }

        private void _headerPictureBox_Paint(object sender, PaintEventArgs e)
        {
                e.Graphics.DrawImage(_backgroundImage, 
                    headerPanel.Width - _backgroundImage.Width,
                    0,
                    _backgroundImage.Width,
                    headerPanel.Height);
                e.Graphics.DrawImage(_headerLogo, headerPanel.Width - 70, 18, _headerLogo.Width,
                        _headerLogo.Height);
                e.Graphics.DrawString(GetHeaderText(), _ci.Theme.GetDataWindowHeaderFont(),
                        new SolidBrush(_ci.Theme.GetDataWindowHeaderFontColor()),
                        _styleGuide.GetDataWindowHeaderLabelPosition());
                e.Graphics.DrawString("Benutzen Sie die Navigationsleiste auf der unteren Seite, um weitere Information anzuzeigen.",
                    new Font("Microsoft Sans Serif", 8, FontStyle.Regular), new SolidBrush(Color.FromArgb(100, 100, 100)),
                    20, 38);
        }

        public void ShowView()
        {
            ShowDialog();
        }

        public IDataNavigationBar NavigationBar
        {
            get { return _navigationBar; }
        }

        public IControllableDataWindowManager<IControllableDataWindowEx<T>> GetWindowManager()
        {
            return _wndManager;
        }

        public IDataSourceProvider<T> DataSourceProvider
        {
            get { return _dataSourceProvider; }
        }

        public bool DataChanged
        {
            get; set;
        }
        
        public bool DataObjectSavedQuery()
        {
            try
            {
                /* Datenobjekt holen und casten */
                ISaveableBusinessObject businessObject = (ISaveableBusinessObject) _dataSourceProvider.GetDataSource();

                /* Wenn die ID != 0, dann wurde das Objekt bereits gespeichert.
                 * Funktion kann hier beendet werden. */
                if (businessObject.ID != 0)
                    return true;

                if (MessageBox.Show("Möchten Sie etwaige Änderungen speichern ?", "Änderungen speichern", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question,
                   MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
                {
                    _wndManager.SaveDataWindows();
                    return true;
                }
            }
            catch (InvalidCastException castEx)
            {
                DisplayError(
                    "Das Datenobjekt ist kein gültiges ISaveableBusinessObject. Es konnte nicht geprüft werden, ob das Objekt bereits gespeichert wurde");
            }
            catch(Exception e)
            {
                DisplayError(e.Message);
            }

            /* Bei irgendeinem Fehler wird false zurückgegeben. */
            return false;
        }

        private void onClick(object sender, EventArgs e)
        {
            if (sender == acceptButton)
            {
                try
                {
                    _wndManager.SaveDataWindows();
                    DataChanged = true;
                }
                catch (Exception ex)
                {
                    DisplayError(ex.Message);
                    
                }
                
            }
            else if (sender == saveButton)
            {
                try
                {
                    _wndManager.SaveDataWindows();
                    DataChanged = true;
                    DialogResult = System.Windows.Forms.DialogResult.OK;
                    Close();
                }
                catch (Exception ex)
                {
                    DisplayError(ex.Message);

                }
            }
            else if (sender == cancelButton)
            {
                /* Hier DataChanged nicht verändert, da dies
                 * bereits durch Übernehmen auf true gesetzt sein
                 * kann */
                DialogResult = System.Windows.Forms.DialogResult.Cancel;
                Close();
            }
        }

        #region Implementation of IErrorDisplayable

        public void DisplayError(string message)
        {
            MessageBox.Show(message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion

        private void AbstractContainerWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            /* Prüfen, ob sich mindestens ein Fenster geändert hat. */
            IList<IControllableDataWindowEx<T>> windows = _wndManager.GetWindows();
            var changed = false;
            foreach (IControllableDataWindowEx<T> window in windows)
            {
                if (window.HasInputChanged)
                {
                    changed = true;
                    break;
                }
            }
            
            if ((this.DialogResult == System.Windows.Forms.DialogResult.Cancel) && (changed))
            {
                DialogResult result = MessageBox.Show("Möchten Sie die Änderungen speichern ?", "Änderungen speichern",
                                                      MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question,
                                                      MessageBoxDefaultButton.Button1);
                if (result == DialogResult.Yes)
                {
                    /* Die Änderungen sollen gespeichert werden */
                    try
                    {
                        _wndManager.SaveDataWindows();
                        DataChanged = true;
                    }
                    catch (Exception ex)
                    {
                        DisplayError(ex.Message);
                        e.Cancel = true;
                    }
                }
                else if (result == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }
    }
}
